package cn.com.bluemoon.daps.model.core.file.validator;

import lombok.extern.slf4j.Slf4j;

import javax.validation.ConstraintValidator;
import javax.validation.ConstraintValidatorContext;
import java.util.Collections;
import java.util.Optional;
import java.util.Set;
import java.util.TreeSet;


/**
 * excel导入中下拉项校验
 *
 * @author Jarod.Kong
 * @date 2021/3/15 14:25
 */
@Slf4j
public abstract class BaseExcelSelectOptionValidator implements ConstraintValidator<MyExcelYesNoSelectOption, String> {

    /**
     * @return 获取下拉符合项
     */
    protected abstract Set<String> getSelectOptions();

    /**
     * 默认针对下拉的内容是忽略大小写的字符串
     *
     * @return t / f
     */
    protected boolean compareCaseInsensitive() {
        return true;
    }

    /**
     * @param constraintAnnotation annotation instance for a given constraint declaration
     */
    @Override
    public void initialize(MyExcelYesNoSelectOption constraintAnnotation) {
    }


    /**
     * <important>
     * compareCaseInsensitive()=true下，getSelectOptions()不可存在为null的值，due to TreeSet不可存null, skipped
     * </important>
     *
     * @return 忽略字符串大小写
     */
    private TreeSet<String> getSelectOptionCaseInsensitive() {
        TreeSet<String> s1 = new TreeSet<>(String.CASE_INSENSITIVE_ORDER);
        if (getSelectOptions() != null && !getSelectOptions().isEmpty()) {
            // 需要注意treeSet的内容不可以为null，所以要发出警告，同时过滤掉
            for (String selectOption : getSelectOptions()) {
                if (selectOption == null) {
                    log.warn("compareCaseInsensitive()=true下，getSelectOptions()不可存在为null的值，due to TreeSet不可存null, skipped");
                } else {
                    s1.add(selectOption);
                }
            }
        }
        return s1;
    }

    /**
     * true
     * 1.为空
     * 2.为null
     * 3.有效下拉
     *
     * @param value   object to validate
     * @param context context in which the constraint is evaluated
     * @return {@code false} if {@code value} does not pass the constraint
     */
    @Override
    public boolean isValid(String value, ConstraintValidatorContext context) {
        if (value == null) {
            return true;
        }
        if (value.trim().isEmpty()) {
            return true;
        }
        return compareCaseInsensitive() ?
                getSelectOptionCaseInsensitive().contains(value) :
                Optional.ofNullable(getSelectOptions()).orElse(Collections.emptySet()).contains(value);
    }
}
